home *** CD-ROM | disk | FTP | other *** search
- /* PROGRAM R.Tutor */
- /* (a home-grown tutorial for writing applications using resources */
- /* Part 1 - starting up & shutting down the tools from a ToolStartup */
- /* list kept in a resource */
- /* Part 2 - add a menu bar that is kept in a resource */
- /* Part 3 - add the event loop so that the menus "come alive" and put up a */
- /* window that is defined in the resource fork */
-
- #include <types.h>
- #include <INTMATH.h>
- #include <MEMORY.h>
- #include <MISCTOOL.h>
- #include <LOCATOR.h>
- #include <DESK.H>
- #include <QUICKDRAW.h>
- #include <EVENT.h>
- #include <CONTROL.h>
- #include <WINDOW.h>
- #include <MENU.h>
- #include <GSOS.h>
- #include <Resources.h>
-
- #define kStartStopID 1L /* used when starting and shutting down tools */
-
- /*---------------------- Menus & Menu Bars ---------------------------*/
- #define kMenuBarID 1L /* resource ID of the menu bar itself */
-
- /* define all the menu id's */
- #define kAppleMenuID 1000 /* resource ID of the Apple menu */
- #define kFileMenuID 2000 /* resource ID of the File menu */
- #define kEditMenuID 3000 /* resource ID of the Edit menu */
-
- /* now, define the menu item id's */
- #define kAboutBoxID 1001 /* resource ID of the About Box menu item */
-
- #define kNewItemID 2001 /* resource ID of the New Item in File menu */
- #define kOpenItemID 2002 /* resource ID of the Open item in File menu */
- #define kCloseItemID 255 /* the "Close" item */
- #define kSaveItemID 2004 /* the "Save" item */
- #define kSaveAsItemID 2005 /* the "Save As..." item */
- #define kRevertItemID 2006 /* the "Revert to Saved" item */
- #define kPageItemID 2007 /* the "Page Setup..." item */
- #define kPrintItemID 2008 /* the "Print..." item */
- #define kQuitItemID 2009 /* the "Quit" item */
-
- #define kUndoItemID 250 /* the "Undo" item */
- #define kCutItemID 251 /* the "Cut" item */
- #define kCopyItemID 252 /* the "Copy" item */
- #define kPasteItemID 253 /* the "Paste" item */
- #define kClearItemID 254 /* the "Clear" item */
- #define kSelectItemID 3001 /* the "Select All" item */
- #define kShowClipItemID 3002 /* the "Show ClipBoard" item */
-
- /* define the resource ID's for all windows used by this app */
- #define myWindowID 2362L /* window's resource ID = 2362 */
-
- /* declare the constants for our TaskMaster event mask */
- #define kMyTaskMask 0x001FFFFFL /* this mask is for TaskMaster itself */
- #define kMyEventMask 0xFFFF /* this mask is passed to GetNextEvent */
-
- /* declare the global variable that we'll use with TaskMaster */
- WmTaskRec gMyEvent;
-
-
- /* declare all of the global variables that we'll be using */
- unsigned gMyMemID; /* holds the ID returned by MMStartup */
- Ref gToolListRef; /* the list of tools used to start and stop the tools */
- Boolean gPunt; /* TRUE if it's time to quit the app */
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for putting up the About box */
-
- do_show_about()
- {
- /* empty for now - just beep */
- SysBeep();
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for quitting the app */
-
- do_quit_app()
- {
- /* we actually just set the "quit" flag and let the real quitting happen */
- /* in the main event loop. Later, we would add code here to cope with */
- /* closing all open windows, saving their contents, etc. */
-
- gPunt = TRUE;
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for dealing with items picked */
- /* from the menus by the user */
-
- do_menu_events()
- {
-
- unsigned int pickedMenuID; /*ID of menu the user just picked an item from */
- unsigned int pickedItemID; /* ID of item the user just picked */
-
- /* the hi-word of wmTaskData is the menu ID */
- pickedMenuID = HiWord(gMyEvent.wmTaskData);
-
- /* the lo-word of wmTaskData is the item ID */
- pickedItemID = LoWord(gMyEvent.wmTaskData);
-
- switch(pickedItemID)
- {
- case kAboutBoxID : do_show_about(); /* show the About box */
- break;
- case kNewItemID : break; /* that's all for this item */
- case kOpenItemID : break; /* that's all for this item */
- case kCloseItemID : break; /* that's all for this item */
- case kSaveItemID : break; /* that's all for this item */
- case kSaveAsItemID : break; /* that's all for this item */
- case kRevertItemID : break; /* that's all for this item */
- case kPageItemID : break; /* that's all for this item */
- case kPrintItemID : break; /* that's all for this item */
- case kQuitItemID : do_quit_app(); /* sets gPunt to TRUE */
- break;
- case kUndoItemID : break; /* that's all for this item */
- case kCutItemID : break; /* that's all for this item */
- case kCopyItemID : break; /* that's all for this item */
- case kPasteItemID : break; /* that's all for this item */
- case kClearItemID : break; /* that's all for this item */
- case kSelectItemID : break; /* that's all for this item */
- case kShowClipItemID : break; /* that's all for this item */
-
- default: ; /* always have a default action in case something goes wrong */
-
- } /* end of the "switch" statement */
-
- /* Turn off the highlighting on the menu the user picked the item from. */
- /* Then return to the main event loop to see what we'll do next. */
- HiliteMenu(FALSE,pickedMenuID);
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure installs the menu bar from a resource */
-
- do_make_menus()
- {
- MenuBarRecHndl my_mbar_hndl;
- word menu_bar_height;
- {
-
- /* the next three calls are ALL required to bring the menu bar in from */
- /* the resource fork AND make it the current system menu bar. For */
- /* details, see the IIGS Toolbox Reference, under NewMenuBar2 */
- my_mbar_hndl = NewMenuBar2(refIsResource, kMenuBarID, nil);
- SetSysBar(my_mbar_hndl);
- SetMenuBar(nil);
-
- /* now, add NDA's, adjust the sizes of the menus, and draw the menu bar */
- /* kAppleMenuID used to be defined as a long and had to be cast to a */
- /* word here. It's been redefined to be only a word in size, so the */
- /* casting is no longer needed. */
- FixAppleMenu(kAppleMenuID); /* adds NDA's */
- menu_bar_height = FixMenuBar(); /* adjust the sizes */
- DrawMenuBar(); /* draw the new menu bar and enjoy! */
- }
- }
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for starting the tools (using the */
- /* list in a resource) if the SartupTools call fails, then gPunt will */
- /* contain "TRUE", so we can abort the app the global variable for this app's */
- /* memory id is acquired here as well. */
-
- do_init_rom()
- {
- gMyMemID = _ownerid; /* find out our memory id & save it for later */
-
- /* crank 'em up! - make sure that kStartStopID is defined as a long!!! */
- gToolListRef = StartUpTools(gMyMemID,refIsResource,kStartStopID);
-
- if (_toolErr == noError)
- { /* there was no error, so the app can continue starting up */
- gPunt = FALSE;
- }
- else
- { /* something went wrong, so set gPunt to indicate the failure */
- gPunt = TRUE;
- }
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure draws the contents of the window that we created */
- /* from the template in the resource fork. Any time the window's content */
- /* region needs to be redrawn, this routine gets called. Put a SysBeep() */
- /* call in here if you want to investigate when this routine gets called. */
- /* That will cause a beep every time this routine gets called... */
-
- drawMyContents()
- {
- /* since all of the contents of our window are actually controls right */
- /* now, we can redraw the contents just by calling DrawControls. Later, */
- /* we could add code to draw other, non-control stuff. */
-
- GrafPortPtr currentGrafPortPtr; /* pointer to current Graf Port */
-
- currentGrafPortPtr = GetPort(); /* grab the pointer to current port */
- DrawControls(currentGrafPortPtr); /* draw the controls in that port */
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure creates a window using a template that is kept */
- /* in the application's resource fork */
-
- do_make_window()
- {
- /* since we only have one window and it can't be closed, we won't */
- /* bother to keep the grafPortPtr in a global. We can always get it */
- /* back by calling FrontWindow(). Later, when we add multiple windows, */
- /* we'll want a better way to keep track of the grafPortPtr to each */
- /* window, but for now I'd like to keep it simple. */
-
- GrafPortPtr myWndwPtr;
- CtlRecHndl myCtlRecHndl;
-
- myWndwPtr = NewWindow2(NIL, /* use "default" title string from param block */
- NIL, /* use "default" refCon from param block */
- drawMyContents, /* procedure that draws contents */
- NIL, /* use std def proc for this window */
- refIsResource, /* template is in a resource */
- myWindowID, /* resource ID of our window */
- rWindParam1); /* template is of param type 1 */
-
- /* According to Apple IIGS Tech Note #82 (Controlling the Control Mgr) */
- /* NewWindow2 does NOT set the grafPort to the newly created grafPort */
- /* so it's possible for our controls to NOT be installed correctly */
- /* and for the call to trash memory. So, we avoid the problem by doing */
- /* exactly waht Tech Note #82 tells us to do -> don't let NewWindow2 */
- /* install our controls for us. We do this by putting NIL in the */
- /* "p1ControlList" field of the rWindParam1 record (in our Rez source) */
- /* and calling NewControl2 to put the controls in the window - AFTER */
- /* setting the grafPort ourselves! */
-
- SetPort(myWndwPtr); /* set the Graf Port to the newly created window's */
- myCtlRecHndl = NewControl2(myWndwPtr, /* window to put controls in */
- resourceToResource, /* list is in resource */
- myWindowID); /* resource ID of control list */
- }
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is the main event loop. It runs until gPunt is */
- /* set to TRUE by the user picking "Quit" from the File menu. */
-
- do_main_event()
- {
- word myTaskCode; /* used to hold the task codes returned by Task Master */
-
- /* tell Task Master which events it can do */
- /* we're lazy, so let it handle everything possible! */
- gMyEvent.wmTaskMask = kMyTaskMask;
-
- while(!gPunt) /* keep calling Task Master until "Quit" has been selected */
- {
- myTaskCode = TaskMaster(kMyEventMask, &gMyEvent);
- switch(myTaskCode)
- {
- case wInGoAway:
- break;
- case wInSpecial:
- case wInMenuBar:
- do_menu_events();
- break;
- default: break; /* always have a default */
- } /* end of the switch statement */
- } /* end of the "while" */
- } /* end of do_main_event */
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is the main application itself. */
- /* don't forget to add the code that will check the message center to see if */
- /* this app was launched by clicking on its icon or by clicking on a data */
- /* file created by this app. If the data file was clicked on, then grab its */
- /* name out of the message center and open it instead of opening the */
- /* untitled window. */
-
- main()
- {
- do_init_rom(); /* get my memory id, start the tools, & set gPunt */
- if (gPunt == FALSE)
- {
- do_make_menus(); /* insert the menu bar */
- do_make_window(); /* create a new window from the resource fork */
- InitCursor(); /* this changes the cursor to the "normal" one. */
- /* It was left as a watch cursor when the tools */
- /* were started up. */
- do_main_event();
- }
- ShutDownTools(refIsHandle,gToolListRef); /* shut down the tools and quit */
- } /* end of main program */
-